package com.ruoyi.base.service.impl;

import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.ruoyi.base.domain.BaseProperty;
import com.ruoyi.base.domain.BaseSystem;
import com.ruoyi.base.domain.BaseType;
import com.ruoyi.base.service.IBasePropertyService;
import com.ruoyi.base.service.IBaseSystemService;
import com.ruoyi.base.service.IBaseTypeService;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.DictUtils;
import com.ruoyi.common.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.base.mapper.BaseDeviceMapper;
import com.ruoyi.base.domain.BaseDevice;
import com.ruoyi.base.service.IBaseDeviceService;

import javax.annotation.PostConstruct;

/**
 * 设备信息Service业务层处理
 * 
 * @author yepanpan
 * @date 2025-02-28
 */
@Service
public class BaseDeviceServiceImpl implements IBaseDeviceService 
{
    public static final String CACHE_MAP = "base_device";
    private static final Logger log = LoggerFactory.getLogger(BaseDeviceServiceImpl.class);
    private static Map<String, Field> fieldMap = Arrays.stream(BaseDevice.class.getDeclaredFields()).collect(Collectors.toMap(Field::getName, Field->Field));
    @Autowired
    private RedisCache redisCache;

    @Autowired
    private BaseDeviceMapper baseDeviceMapper;
    @Autowired
    private IBasePropertyService basePropertyService;
    @Autowired
    private IBaseTypeService baseTypeService;
    private IBaseSystemService baseSystemService;

    @PostConstruct
    public int reCache(){
        redisCache.deleteObject(CACHE_MAP);
        return 0;
    }

    /**
     * 查询设备信息
     *
     * @param code 设备代码
     * @return 设备信息
     */
    @Override
    public BaseDevice selectBaseDeviceByCode(String code){
        String key = "code_"+code;
        Long id = redisCache.getCacheMapValue(CACHE_MAP, key);
        if(id != null){
            return selectBaseDeviceById(id);
        }
        BaseDevice baseDevice = baseDeviceMapper.selectBaseDeviceByCode(code);
        if(baseDevice == null){
            return null;
        }
        redisCache.setCacheMapValue(CACHE_MAP, key, baseDevice.getId());
        redisCache.setCacheMapValue(CACHE_MAP, "id_"+id, baseDevice);
        if(StringUtils.isNotEmpty(baseDevice.getExtCode())){
            redisCache.setCacheMapValue(CACHE_MAP, "ext_"+baseDevice.getExtCode(), baseDevice.getId());
        }
        return baseDevice;
    }

    /**
     * 查询设备信息
     *
     * @param extCode 设备业务编码
     * @return 设备信息
     */
    @Override
    public BaseDevice selectBaseDeviceByExtCode(String extCode){
        String key = "ext_"+extCode;
        Long id = redisCache.getCacheMapValue(CACHE_MAP, key);
        if(id != null){
            return selectBaseDeviceById(id);
        }
        BaseDevice baseDevice = baseDeviceMapper.selectBaseDeviceByExtCode(extCode);
        if(baseDevice == null){
            return null;
        }
        redisCache.setCacheMapValue(CACHE_MAP, key, baseDevice.getId());
        redisCache.setCacheMapValue(CACHE_MAP, "code_"+baseDevice.getCode(), baseDevice.getId());
        redisCache.setCacheMapValue(CACHE_MAP, "id_"+id, baseDevice);
        return baseDevice;
    }

    /**
     * 查询设备信息
     * 
     * @param id 设备信息主键
     * @return 设备信息
     */
    @Override
    public BaseDevice selectBaseDeviceById(Long id)
    {
        String key = "id_"+id;
        BaseDevice baseDevice = redisCache.getCacheMapValue(CACHE_MAP, key);
        if(baseDevice != null){
            return baseDevice;
        }

        baseDevice = baseDeviceMapper.selectBaseDeviceById(id);
        if(baseDevice == null){
            return null;
        }

        redisCache.setCacheMapValue(CACHE_MAP, key, baseDevice);
        redisCache.setCacheMapValue(CACHE_MAP, "code_"+baseDevice.getCode(), id);
        if(StringUtils.isNotEmpty(baseDevice.getExtCode())){
            redisCache.setCacheMapValue(CACHE_MAP, "ext_"+baseDevice.getExtCode(), id);
        }
        return baseDevice;
    }

    /**
     * 查询设备信息列表
     * 
     * @param baseDevice 设备信息
     * @return 设备信息
     */
    @Override
    public List<BaseDevice> selectBaseDeviceList(BaseDevice baseDevice)
    {
        if(StringUtils.isNotEmpty(baseDevice.getTypeCode())){
            String[] typeCodes = baseDevice.getTypeCode().split(",");
            Long[] ids = new Long[typeCodes.length];
            for(int i=0;i<typeCodes.length;i++){
                BaseType baseType = baseTypeService.selectBaseTypeByCode(typeCodes[i]);
                if(baseType == null) {
                    ids[i] = 0L;
                }else{
                    ids[i] = baseType.getId();
                }
            }
            baseDevice.getParams().put("typeIds", StringUtils.join(ids, ","));
        }
        if(StringUtils.isNotEmpty(baseDevice.getSysCode())){
            BaseSystem baseSystem = baseSystemService.selectBaseSystemByCode(baseDevice.getSysCode());
            if(baseSystem != null){
                baseDevice.setSysId(baseSystem.getId());
            }else{
                return null;
            }
        }
        return baseDeviceMapper.selectBaseDeviceList(baseDevice);
    }

    /**
     * 新增设备信息
     * 
     * @param baseDevice 设备信息
     * @return 结果
     */
    @Override
    public synchronized int insertBaseDevice(BaseDevice baseDevice)
    {
        BaseDevice old = selectBaseDeviceByCode(baseDevice.getCode());
        if(old != null){
            throw new ServiceException("设备已存在:"+baseDevice.getCode());
        }

        validate(baseDevice);

        baseDevice.setCreateTime(DateUtils.getNowDate());
        return baseDeviceMapper.insertBaseDevice(baseDevice);
    }

    /**
     * 验证数据
     * @param baseDevice
     * @return
     */
    public void validate(BaseDevice baseDevice){
        List<BaseProperty> list = basePropertyService.selectBasePropertyByTypeId(baseDevice.getTypeId());
        try {
            for (BaseProperty property : list) {
                Field f = fieldMap.get(StringUtils.toCamelCase(property.getCode()));
                f.setAccessible(true);
                Object v = f.get(baseDevice);
                if (property.getIsRequired().equals("Y") && v == null) {
                    throw new ServiceException(property.getLabel() + "不能为空");
                }
                if (v == null) {
                    continue;
                }
                if (property.getFormType().equalsIgnoreCase("radio") || property.getFormType().equalsIgnoreCase("checkbox")) {
                    String[] vs = v.toString().split(",");
                    for (String dv : vs) {
                        if (StringUtils.isEmpty(DictUtils.getDictLabel(property.getDsCode(), dv))) {
                            throw new ServiceException(property.getLabel() + "的值无效");
                        }
                    }
                }
            }
        }catch (Exception e){
            e.printStackTrace();
            throw new ServiceException("校验设备信息失败：" + e.getMessage());
        }
    }

    /**
     * 修改设备信息
     * 
     * @param baseDevice 设备信息
     * @return 结果
     */
    @Override
    public synchronized int updateBaseDevice(BaseDevice baseDevice)
    {
        validate(baseDevice);
        baseDevice.setUpdateTime(DateUtils.getNowDate());
        return baseDeviceMapper.updateBaseDevice(baseDevice) + reCache();
    }

    /**
     * 修改设备状态，不验证自定义属性
     *
     * @param baseDevice 设备信息
     * @return 结果
     */
    @Override
    public synchronized int updateBaseDeviceStatus(BaseDevice baseDevice){
        baseDevice.setUpdateTime(DateUtils.getNowDate());
        return baseDeviceMapper.updateBaseDevice(baseDevice) + reCache();
    }

    /**
     * 批量删除设备信息
     * 
     * @param ids 需要删除的设备信息主键
     * @return 结果
     */
    @Override
    public synchronized int deleteBaseDeviceByIds(Long[] ids)
    {
        return baseDeviceMapper.deleteBaseDeviceByIds(ids) + reCache();
    }

    /**
     * 删除设备信息信息
     * 
     * @param id 设备信息主键
     * @return 结果
     */
    @Override
    public synchronized int deleteBaseDeviceById(Long id)
    {
        return baseDeviceMapper.deleteBaseDeviceById(id) + reCache();
    }
}
